package module

import (
	"context"
	"fmt"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	logger "platon-tools/go-service/go-logger"
	"platon-tools/go-service/service"
	"sync/atomic"
	"time"
)

var (
	dbConnectTimeout = 60 * time.Second
)

type MysqlDB struct {
	*gorm.DB

	service *service.Service

	ctx    context.Context
	cancel context.CancelFunc

	latestBlock uint64

	running int32
}

func (m *MysqlDB) IsRunning() bool {
	if atomic.LoadInt32(&m.running) == 1 {
		return true
	}
	return false
}

func (m *MysqlDB) Close() error {
	if m.IsRunning() {
		atomic.StoreInt32(&m.running, 0)
		m.cancel()
		return m.DB.Close()
	}

	return nil
}

func (m *MysqlDB) Start(ctx context.Context, config *service.Config, s *service.Service) error {

	fmt.Println("mysql init start")

	m.ctx, m.cancel = context.WithCancel(ctx)
	m.service = s

	sugar := logger.Logger.Sugar()

	mysqlUrl := fmt.Sprintf("%s:%s@(%s:3306)/%s?charset=utf8mb4&parseTime=True&loc=Local", config.Mysql.User, config.Mysql.Pass, config.Mysql.IP, config.Mysql.Table)
	db, err := gorm.Open("mysql", mysqlUrl)
	if err != nil {
		sugar.Errorf("testing connect to mysql (url=%s) failed err:%s", mysqlUrl, err)
		panic(err)
	}
	db.Debug()
	db.LogMode(true)

	db.DB().SetMaxIdleConns(10)
	db.DB().SetMaxOpenConns(100)

	m.DB = db

	atomic.StoreInt32(&m.running, 1)
	go m.eventLoop()

	fmt.Println("mysql init success")

	return nil
}

func (m *MysqlDB) eventLoop() {
	defer m.Close()

	sugar := logger.Logger.Sugar()

	for {
		select {
		case <-m.ctx.Done():
			sugar.Infof("redis db event loop quit timer: %s", time.Now().String())
			return
		}
	}
}

func (m *MysqlDB) Name() string {
	return "MYSQLDB"
}
